package com.kexio.auth.mybatis;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.kexio.auth.config.TenantModeProperties;
import com.kexio.auth.config.TenantModeProperties.TenantMode;
import com.kexio.auth.context.TenantContextHolder;
import com.kexio.auth.util.AuthContextUtils;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;

/**
 * 灵活的租户行级处理器
 * 
 * 基于租户模式动态决定是否启用租户行级过滤：
 * - DISABLED: 不进行租户过滤
 * - ROW_LEVEL: 启用租户过滤
 * - INSTANCE_LEVEL: 不进行租户过滤（通过数据源隔离）
 * - HYBRID: 动态决定（根据租户是否有独立数据源）
 * 
 * @author Kexio Team
 * @since 2.0.0
 */
@Component
public class FlexibleTenantLineHandler implements TenantLineHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(FlexibleTenantLineHandler.class);
    
    private final TenantModeProperties tenantModeProperties;
    
    @Autowired
    public FlexibleTenantLineHandler(TenantModeProperties tenantModeProperties) {
        this.tenantModeProperties = tenantModeProperties;
        logger.debug("初始化灵活租户行级处理器，租户模式: {}", 
                    tenantModeProperties != null ? tenantModeProperties.getMode() : "未配置");
    }
    
    /**
     * 获取租户ID表达式
     * 
     * 根据租户模式和当前上下文决定是否返回租户ID
     */
    @Override
    public Expression getTenantId() {
        // 检查是否应用租户过滤
        boolean shouldFilter = shouldApplyTenantFilter();
        
        if (!shouldFilter) {
            logger.debug("租户过滤已禁用，返回 null");
            return null;
        }
        
        // 检查当前用户是否为跨租户超级管理员
        if (isCrossTenantSuperAdmin()) {
            logger.debug("跨租户超级管理员，跳过租户过滤");
            return null;
        }
        
        // 从统一API获取租户ID
        String tenantId = AuthContextUtils.getCurrentTenantId();
        logger.trace("获取租户ID: {}", tenantId);
        
        if (!StringUtils.hasText(tenantId)) {
            logger.debug("当前租户ID为空，跳过租户过滤");
            return null;
        }
        
        logger.debug("应用租户过滤，租户ID: '{}'", tenantId);
        return new StringValue(tenantId);
    }
    
    /**
     * 获取租户字段名
     */
    @Override
    public String getTenantIdColumn() {
        if (tenantModeProperties != null && 
            tenantModeProperties.getRowLevel() != null && 
            StringUtils.hasText(tenantModeProperties.getRowLevel().getTenantColumn())) {
            return tenantModeProperties.getRowLevel().getTenantColumn();
        }
        return "tenant_id"; // 默认字段名
    }
    
    /**
     * 判断表是否忽略租户过滤
     */
    @Override
    public boolean ignoreTable(String tableName) {
        if (!StringUtils.hasText(tableName)) {
            return true;
        }
        
        // 检查配置的忽略表（统一配置管理）
        if (tenantModeProperties != null && 
            tenantModeProperties.getRowLevel() != null && 
            tenantModeProperties.getRowLevel().getIgnoreTables() != null) {
            
            List<String> ignoreTables = tenantModeProperties.getRowLevel().getIgnoreTables();
            boolean ignored = ignoreTables.stream()
                .anyMatch(ignoreTable -> ignoreTable.equalsIgnoreCase(tableName));
            
            if (ignored) {
                logger.debug("表 {} 在配置忽略列表中，跳过租户过滤", tableName);
                return true;
            }
        }
        
        logger.debug("表 {} 需要应用租户过滤", tableName);
        return false;
    }
    
    /**
     * 判断是否应该应用租户过滤
     */
    private boolean shouldApplyTenantFilter() {
        if (tenantModeProperties == null) {
            logger.debug("租户配置为空，不应用租户过滤");
            return false;
        }
        
        if (!tenantModeProperties.isEnabled()) {
            logger.debug("租户功能未启用，不应用租户过滤");
            return false;
        }
        
        TenantMode mode = tenantModeProperties.getMode();
        if (mode == null) {
            logger.debug("租户模式未配置，不应用租户过滤");
            return false;
        }
        
        switch (mode) {
            case DISABLED:
                logger.debug("租户模式为DISABLED，不应用租户过滤");
                return false;
                
            case ROW_LEVEL:
                logger.debug("租户模式为ROW_LEVEL，应用租户过滤");
                return true;
                
            case INSTANCE_LEVEL:
                logger.debug("租户模式为INSTANCE_LEVEL，不应用租户过滤（通过数据源隔离）");
                return false;
                
            case HYBRID:
                // 混合模式：检查当前租户是否有独立数据源
                return shouldApplyTenantFilterInHybridMode();
                
            default:
                logger.warn("未知的租户模式: {}，不应用租户过滤", mode);
                return false;
        }
    }
    
    /**
     * 检查当前用户是否为跨租户超级管理员
     * 
     * 注意：直接从Session获取用户信息，避免在权限查询过程中再次触发Sa-Token角色检查造成循环调用
     */
    private boolean isCrossTenantSuperAdmin() {
        try {
            // 检查是否已登录
            if (!cn.dev33.satoken.stp.StpUtil.isLogin()) {
                return false;
            }
            
            // 直接从Session获取用户信息，避免循环调用
            Object userInfoObj = cn.dev33.satoken.stp.StpUtil.getSession().get("userInfo");
            if (userInfoObj instanceof com.kexio.auth.dto.UserAuthInfo) {
                com.kexio.auth.dto.UserAuthInfo userInfo = (com.kexio.auth.dto.UserAuthInfo) userInfoObj;
                
                // 检查用户角色是否包含超级管理员
                if (userInfo.getRoles() != null) {
                    return userInfo.getRoles().stream()
                        .anyMatch(role -> "SUPER_ADMIN".equals(role.getRoleCode()) || 
                                         "ROLE_SUPER_ADMIN".equals(role.getRoleCode()) ||
                                         "role_super_admin".equals(role.getRoleCode()));
                }
            }
            
            // 降级: 如果无法从Session获取用户信息，则不跳过租户过滤（保守做法）
            logger.debug("无法从Sa-Token Session获取用户信息，不跳过租户过滤");
            return false;
                                    
        } catch (Exception e) {
            logger.debug("检查超级管理员角色失败: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 混合模式下判断是否应用租户过滤
     */
    private boolean shouldApplyTenantFilterInHybridMode() {
        String tenantId = TenantContextHolder.getCurrentTenantId();
        if (!StringUtils.hasText(tenantId)) {
            logger.debug("混合模式下租户ID为空，不应用租户过滤");
            return false;
        }
        
        // 检查当前租户是否有独立数据源配置
        if (tenantModeProperties.getInstanceLevel() != null && 
            tenantModeProperties.getInstanceLevel().getTenantDataSourceMapping() != null) {
            
            boolean hasInstanceMapping = tenantModeProperties.getInstanceLevel()
                .getTenantDataSourceMapping()
                .containsKey(tenantId);
            
            if (hasInstanceMapping) {
                logger.debug("混合模式下租户 {} 有独立数据源，不应用租户过滤", tenantId);
                return false;
            }
        }
        
        logger.debug("混合模式下租户 {} 使用行级隔离，应用租户过滤", tenantId);
        return true;
    }
    
    /**
     * 获取当前配置的详细信息，用于调试
     */
    public String getConfigInfo() {
        if (tenantModeProperties == null) {
            return "FlexibleTenantLineHandler{tenantModeProperties=null}";
        }
        
        return String.format("FlexibleTenantLineHandler{enabled=%s, mode=%s, tenantColumn='%s', ignoreTables=%s}", 
                           tenantModeProperties.isEnabled(),
                           tenantModeProperties.getMode(),
                           getTenantIdColumn(),
                           tenantModeProperties.getRowLevel() != null ? 
                               tenantModeProperties.getRowLevel().getIgnoreTables() : "[]");
    }
    
    @Override
    public String toString() {
        return getConfigInfo();
    }
}
